﻿#include "../../x/draw/draw.h"
#include "../../interface/IRound.h"
#include <cstdio>

const swui::ctlRect swui::ctlSingleLabel::defaultPaddingRect = ctlRect(3, 2, 3, 2);

#define MK_ADDITION_4 \
		if(gradient->colorFormat == ctlColorFormat::rgb)\
		{\
			border.crBegin |= 0xff000000;\
			border.crEnd |= 0xff000000;\
			fill.crBegin |= 0xff000000;\
			fill.crEnd |= 0xff000000;\
		}

#define MK_ADDITION_2 \
		if(solid->colorFormat == ctlColorFormat::rgb)\
		{\
			border |= 0xff000000;\
			fill |= 0xff000000;\
		}

#define MAKE_POSITION(obj)	\
	int left = obj.x, top = obj.y,	\
		bottom = obj.cy + top, right = obj.cx + left,	\
		width = obj.cx, height = obj.cy

#define MAKE_POSITION2(obj)	\
	int left = obj->getLeft(), top = obj->getTop(),	\
		bottom = obj->getBottom(), right = obj->getRight(),	\
		width = obj->getWidth(), height = obj->getHeight()

namespace swui
{
	void ctlRoot::_alpha_redraw_(_ctlInterior::drawInfo* info)
	{
		if(getControlAlpha() == 255) _redraw_(info);
		else if(getControlAlpha() != 0) {
			_eventTrans.getMajorInfo()->tempAlpha.require(
				getRoot()->getWidth(), getRoot()->getHeight());
			_ctlInterior::drawInfo tempInfo = *info;
			tempInfo.hDC = _eventTrans.getMajorInfo()->tempAlpha.getDC();
			tempInfo.graphics = _eventTrans.getMajorInfo()->tempAlpha.getGdip();
			SelectClipRgn(tempInfo.hDC, info->drawRegion);
			BitBlt(tempInfo.hDC, getLeft(), getTop(), getWidth(), getHeight(), 
				info->hDC, getLeft(), getTop(), SRCCOPY);
			_redraw_(&tempInfo);
			BLENDFUNCTION bf = {0};
			bf.BlendOp = AC_SRC_OVER;
			bf.SourceConstantAlpha = getControlAlpha();
			AlphaBlend(info->hDC, getLeft(), getTop(), getWidth(), getHeight(), 
				tempInfo.hDC, getLeft(), getTop(), getWidth(), getHeight(), bf);
			SelectClipRgn(tempInfo.hDC, NULL);
		}
	}
	inline static RECT MAKE_RECT(int x, int y, int cx, int cy)
	{
		RECT rc;
		rc.left = x, rc.right = x + cx;
		rc.top = y, rc.bottom = y + cy;
		return rc;
	}
	inline static RECT MAKE_RECT(const ctlRect& r)
	{
		return MAKE_RECT(r.x, r.y, r.cx, r.cy);
	}
	inline static RECT MAKE_RECT_WITH_POINT(const ctlRect&r, const ctlPoint& p)
	{
		return MAKE_RECT(ctlRect(r.x + p.x, r.y + p.y, r.cx, r.cy));
	}

	template<typename ColorType>
	static inline ColorType linear_interpolation(ColorType begin, ColorType end, int value)
	{
		float ofs = static_cast<float>(value) / static_cast<float>
			(ctlSmoothTransform::maxValue - ctlSmoothTransform::minValue);
		unsigned char *data1 = reinterpret_cast<unsigned char*>(&begin),
			*data2 = reinterpret_cast<unsigned char*>(&end);
		ColorType type;
		unsigned char* dest = reinterpret_cast<unsigned char*>(&type);
		for(int i = 0; i != sizeof(ColorType); ++i)
		{
			dest[i] = static_cast<unsigned char>(data1[i] + (static_cast<int>(data2[i]) -
				static_cast<int>(data1[i])) * ofs);
		}
		return type;
	}
	template<typename ColorType, typename StyleType, typename TextColor> inline 
	static void parse_color_data(ctlRoot* root, const StyleType* style, 
		ColorType& border, ColorType& fill, TextColor& text, bool select)
	{
		//解析颜色数据
		ISmoothTransform* control = dynamic_cast<ISmoothTransform*>(root);
		int interpolationValue = style->smooth.enterLeave;
		if(!select)
		{
			if(!control->isEnabled())
				border = style->border.disenable, fill = style->fill.disenable, text = style->text.disenable;
			else if(control->isMouseDown())
				border = style->border.down, fill = style->fill.down, text = style->text.down;
			else if(control->isSmoothTransformEnabled())
			{
				border = linear_interpolation(style->border.stay, style->border.leave, interpolationValue);
				fill = linear_interpolation(style->fill.stay, style->fill.leave, interpolationValue);
				text = style->text.stay;
			} else if(control->isMouseStay()) 
				border = style->border.stay, fill = style->fill.stay, text = style->text.stay;
			else border = style->border.leave, fill = style->fill.leave, text = style->text.leave;
		} else {
			if(!control->isEnabled())
				border = style->selectBorder.disenable, fill = style->selectFill.disenable, text = style->selectText.disenable;
			else if(control->isMouseDown())
				border = style->selectBorder.down, fill = style->selectFill.down, text = style->selectText.down;
			else if(control->isSmoothTransformEnabled())
			{
				border = linear_interpolation(style->selectBorder.stay, style->selectBorder.leave, interpolationValue);
				fill = linear_interpolation(style->selectFill.stay, style->selectFill.leave, interpolationValue);
				text = style->selectText.stay;
			} else if(control->isMouseStay())
				border = style->selectBorder.stay, fill = style->selectFill.stay, text = style->selectText.stay;
			else border = style->selectBorder.leave, fill = style->selectFill.leave, text = style->selectText.leave;
		}
	}

	static void _common_x_text_draw(HDC hDC, ctlColor textcolor, RECT& textRect, 
		_ctlInterior::textpack& pack, UINT align, HFONT fontinstance, int len)
	{
		if(GetTextColor(hDC) != (MAKE_SYSTEM_RGB(textcolor) & 0xffffff))
			SetTextColor(hDC, MAKE_SYSTEM_RGB(textcolor) & 0xffffff);
		HGDIOBJ oldFont;
		oldFont = SelectObject(hDC, fontinstance);
		DrawTextW(hDC, pack.wptr(), len, &textRect, DT_NOPREFIX | align);
		SelectObject(hDC, oldFont);
	}
	static void common_text_draw(_ctlInterior::drawInfo* info, ctlColor textcolor, RECT& textRect, 
		_ctlInterior::textpack& pack, UINT align, HFONT fontinstance, bool alpha,
		_ctlInterior::tempAlphaDC& tempAlpha, int len = -1)
	{
		if(alpha == false || textcolor >> 24 == 0xff)
		{
			_common_x_text_draw(info->hDC, textcolor, textRect, pack, align, fontinstance, len);
		} else {
			int width = textRect.right - textRect.left;
			int height = textRect.bottom - textRect.top;
			tempAlpha.require(width, height);
			BitBlt(tempAlpha.getDC(), 0, 0, width, height, info->hDC, textRect.left, textRect.top, SRCCOPY);
			RECT rc = MAKE_RECT(0, 0, width, height);
			_common_x_text_draw(tempAlpha.getDC(), textcolor, rc, pack, align, fontinstance, len);
			BLENDFUNCTION bf = {0};
			bf.BlendOp = AC_SRC_OVER;
			bf.SourceConstantAlpha = textcolor >> 24;
			AlphaBlend(info->hDC, textRect.left, textRect.top, width, height, 
				tempAlpha.getDC(), 0, 0, width, height, bf);
		}
	}
	//文字绘制部分
	void IFont::_draw_text_(_ctlInterior::drawInfo* info, ctlColor textcolor, ctlRect textRect)
	{
		if(getTextLength() != 0)
		{
			FORMAT_TEXT_ALIGN;
			RECT ttrect = MAKE_RECT_WITH_POINT(textRect, ctlPoint(getLeft(), getTop()));
			bool alpha = _styleBase->colorFormat == ctlColorFormat::rgba;
			common_text_draw(info, textcolor, ttrect, _textpack, format, 
				reinterpret_cast<HFONT>(getFont()->getNativeHandle()), alpha, 
				_eventTrans.getMajorInfo()->tempAlpha);
		}
	}
	void common_draw_line(_ctlInterior::drawInfo* info, ctlColor color, ctlPoint p1, ctlPoint p2)
	{
		if(color >> 24 == 0xff)
		{
			HPEN hPen = CreatePen(PS_SOLID, 1, MAKE_SYSTEM_RGB(color));
			HGDIOBJ hOldPen = SelectObject(info->hDC, hPen);
			MoveToEx(info->hDC, p1.x, p1.y, NULL);
			LineTo(info->hDC, p2.x, p2.y);
			SelectObject(info->hDC, hOldPen);
			DeleteObject(hPen);
		} else {
			Pen pen(MAKE_COLOR32(color));
			reinterpret_cast<Graphics*>(info->graphics)
				->DrawLine(&pen, Point(p1.x, p1.y), Point(p2.x, p2.y));
		}
	}
	void common_gradient_draw_x(_ctlInterior::drawInfo* info, ctlDoubleColor border, ctlDoubleColor fill, 
		bool drawborder, int dir, ctlRect rc)
	{
		TRIVERTEX vertex_border[2], vertex_fill[2];
		MAKE_VERTEX(border, vertex_border);
		MAKE_VERTEX(fill, vertex_fill);
		vertex_border[0].x = vertex_fill[0].x = rc.x;
		vertex_border[0].y = vertex_fill[0].y = rc.y;
		vertex_border[1].x = vertex_fill[1].x = rc.x + rc.cx;
		vertex_border[1].y = vertex_fill[1].y = rc.y + rc.cy;
		vertex_fill[0].x +=1, vertex_fill[0].y += 1;
		vertex_fill[1].x -= 1, vertex_fill[1].y -= 1;

		GRADIENT_RECT gr;
		gr.LowerRight = 1;
		gr.UpperLeft = 0;
		
		if(drawborder) GradientFill(info->hDC, vertex_border, 2, &gr, 1, dir);
		GradientFill(info->hDC, vertex_fill, 2, &gr, 1, dir);
	}
	//绘制普通的渐变矩形
	static ctlColor common_gradient_draw(_ctlInterior::drawInfo* info, ctlRoot* root, ctlStyleBase* styleBase, ctlRect drawrect, bool select = false, 
		bool drawborder = true, bool autoParse = true, ctlDoubleColor xfill = ctlDoubleColor(), ctlDoubleColor xborder = ctlDoubleColor())
	{
		//绘制gradient样式button
		ctlStyleGradient* gradient = static_cast<ctlStyleGradient*>(styleBase);
		MAKE_POSITION(drawrect);
		ctlDoubleColor fill, border;
		ctlColor textColor = 0;
		//获取颜色数据
		if(autoParse)
			parse_color_data(root, gradient, border, fill, textColor, select);
		else fill = xfill, border = xborder;
		//绘制rgba格式的色彩方案
		if(gradient->gradientDirection == ctlStyleGradient::reverse_horizontal ||
			gradient->gradientDirection == ctlStyleGradient::reverse_vertical)
		{
			std::swap(fill.crBegin, fill.crEnd);
			std::swap(border.crBegin, border.crEnd);
		}
		if(gradient->colorFormat == ctlColorFormat::rgba)
		{
			Graphics* graphics = (Graphics*)info->graphics;
			//Color RGBA
			if(gradient->gradientDirection == ctlStyleGradient::horizontal ||
				gradient->gradientDirection == ctlStyleGradient::reverse_horizontal)
			{
				MAKE_GRADIENT_BRUSH32_H(pen_brush, border);
				MAKE_GRADIENT_BRUSH32_H(brush, fill);
				Pen pen(&pen_brush);
				graphics->FillRectangle(&brush, left, top, width - 1, height - 1);
				if(drawborder)
					graphics->DrawRectangle(&pen, left, top, width - 1, height - 1);
			} else {
				MAKE_GRADIENT_BRUSH32(pen_brush, border);
				MAKE_GRADIENT_BRUSH32(brush, fill);
				Pen pen(&pen_brush);
				graphics->FillRectangle(&brush, left, top, width - 1, height - 1);
				if(drawborder)
					graphics->DrawRectangle(&pen, left, top, width - 1, height - 1);
			}
		} else {
			//绘制rgb格式的色彩方案
			UINT dir = GRADIENT_FILL_RECT_V;
			if(gradient->gradientDirection == ctlStyleGradient::horizontal
				|| gradient->gradientDirection == ctlStyleGradient::reverse_horizontal)
				dir = GRADIENT_FILL_RECT_H;
			common_gradient_draw_x(info, border, fill, drawborder, dir, ctlRect(left, top, width, height));
		}
		if(gradient->horizontalLine.withLine
			&& gradient->horizontalLine.pos < (unsigned)root->getHeight())
		{
			common_draw_line(info, gradient->horizontalLine.color, 
				ctlPoint(root->getLeft() + 1, root->getTop() + gradient->horizontalLine.pos),
				ctlPoint(root->getRight() - 1, root->getTop() + gradient->horizontalLine.pos));
		}
		return textColor;
	}
	//绘制普通实色矩形
	static ctlColor common_solid_draw(_ctlInterior::drawInfo* info, ctlRoot* root, ctlStyleBase* styleBase,  ctlRect drawrect, bool select = false, 
		bool drawborder = true, bool autoParse = true, ctlColor xfill = 0, ctlColor xborder = 0)
	{
		//绘制solid样式的button
		ctlStyleSolid* solid = static_cast<ctlStyleSolid*>(styleBase);
		MAKE_POSITION(drawrect);
		ctlColor fill, border, textColor;
		//获取颜色数据
		if(autoParse)
			parse_color_data(root, solid, border, fill, textColor, select);
		else fill = xfill, border = xborder;
		//绘制rgba格式的色彩方案
		if(solid->colorFormat == ctlColorFormat::rgba)
		{
			Graphics* graphics = (Graphics*)info->graphics;
			SolidBrush fillBrush(Color(MAKE_COLOR32(fill)));
			Pen borderPen(Color(MAKE_COLOR32(border)));
			graphics->FillRectangle(&fillBrush, left, top, width - 1, height - 1);
			if(drawborder)
				graphics->DrawRectangle(&borderPen, left, top, width - 1, height - 1);
		} else {
			//绘制rgb格式的色彩方案
			RECT rect = MAKE_RECT(left, top, width, height);
			if(drawborder)
			{
				HBRUSH borderBrush = CreateSolidBrush(MAKE_SYSTEM_RGB(border));
				FillRect(info->hDC, &rect, borderBrush);
				DeleteObject(borderBrush);
			}
			HBRUSH fillBrush = CreateSolidBrush(MAKE_SYSTEM_RGB(fill));
			rect.left += 1, rect.top += 1, rect.right -=1, rect.bottom -=1;
			FillRect(info->hDC, &rect, fillBrush);
			DeleteObject(fillBrush);
		}
		if(solid->horizontalLine.withLine 
			&& solid->horizontalLine.pos < (unsigned)root->getHeight())
		{
			common_draw_line(info, solid->horizontalLine.color, 
				ctlPoint(root->getLeft() + 1, root->getTop() + solid->horizontalLine.pos),
				ctlPoint(root->getRight() - 1, root->getTop() + solid->horizontalLine.pos));
		}
		return textColor;
	}
	//绘制普通的渐变圆形
	static ctlColor common_gradient_draw_circle(_ctlInterior::drawInfo* info, ctlRoot* root, ctlStyleBase* styleBase, ctlRect drawrect, bool select = false, 
		bool drawborder = true, bool autoParse = true, ctlDoubleColor xfill = ctlDoubleColor(), ctlDoubleColor xborder = ctlDoubleColor())
	{
		//绘制gradient样式button
		ctlStyleGradient* gradient = static_cast<ctlStyleGradient*>(styleBase);
		MAKE_POSITION(drawrect);
		ctlDoubleColor fill, border;
		ctlColor textColor = 0;
		//获取颜色数据
		if(autoParse)
			parse_color_data(root, gradient, border, fill, textColor, select);
		else border = xborder, fill = xfill;
		MK_ADDITION_4;
		Graphics* graphics = (Graphics*)info->graphics;
		//Color RGBA
		if(gradient->gradientDirection == ctlStyleGradient::reverse_horizontal ||
			gradient->gradientDirection == ctlStyleGradient::reverse_vertical)
		{
			std::swap(fill.crBegin, fill.crEnd);
			std::swap(border.crBegin, border.crEnd);
		}
		if(gradient->gradientDirection == ctlStyleGradient::horizontal ||
			gradient->gradientDirection == ctlStyleGradient::reverse_horizontal)
		{
			MAKE_GRADIENT_BRUSH32_H(pen_brush, border);
			MAKE_GRADIENT_BRUSH32_H(brush, fill);
			Pen pen(&pen_brush);
			graphics->FillEllipse(&brush, left, top, width - 1, height - 1);
			if(drawborder)
				graphics->DrawEllipse(&pen, left, top, width - 1, height - 1);
		} else {
			MAKE_GRADIENT_BRUSH32(pen_brush, border);
			MAKE_GRADIENT_BRUSH32(brush, fill);
			Pen pen(&pen_brush);
			graphics->FillEllipse(&brush, left, top, width - 1, height - 1);
			if(drawborder)
				graphics->DrawEllipse(&pen, left, top, width - 1, height - 1);
		}
		return textColor;
	}
	//绘制普通实色圆形
	static ctlColor common_solid_draw_circle(_ctlInterior::drawInfo* info, ctlRoot* root, ctlStyleBase* styleBase,  ctlRect drawrect, bool select = false, 
		bool drawborder = true, bool autoParse = true, ctlColor xfill = 0, ctlColor xborder = 0)
	{
		//绘制solid样式的button
		ctlStyleSolid* solid = static_cast<ctlStyleSolid*>(styleBase);
		MAKE_POSITION(drawrect);
		ctlColor fill, border, textColor;
		//获取颜色数据
		if(autoParse)
			parse_color_data(root, solid, border, fill, textColor, select);
		else fill = xfill, border = xborder;
		//绘制rgba格式的色彩方案
		MK_ADDITION_2;
		Graphics* graphics = (Graphics*)info->graphics;
		SolidBrush fillBrush(Color(MAKE_COLOR32(fill)));
		Pen borderPen(Color(MAKE_COLOR32(border)));
		graphics->FillEllipse(&fillBrush, left, top, width - 1, height - 1);
		if(drawborder)
			graphics->DrawEllipse(&borderPen, left, top, width - 1, height - 1);
		return textColor;
	}
	static void round_common_draw(Graphics& graphics, Brush& brush, Pen& pen, 
		int left, int top, int width, int height, IRound* root, bool drawborder)
	{
		unsigned radius = root->getRoundRadius();
		auto dir = root->getRoundDirection();
		if(dir == ctlRoundDirection::all)
		{
			GdiPlusFillRoundRect(graphics, &brush, left, top, width - 1, height - 1, radius);
			if(drawborder)
				GdiPlusDrawRoundRect(graphics, &pen, left, top, width - 1, height - 1, radius);
		} else {
			GdiPlusFillRoundRect(graphics, &brush, left, top, width - 1, height - 1, radius, (unsigned)dir);
			if(drawborder)
				GdiPlusDrawRoundRect(graphics, &pen, left, top, width - 1, height - 1, radius, (unsigned)dir);
		}
	}
	static void round_extra_line(_ctlInterior::drawInfo* info, IRound* root, ctlExtraLine horizontalLine)
	{
		if(horizontalLine.withLine && horizontalLine.pos < (unsigned)root->getHeight())
		{
			unsigned radius = root->getRoundRadius();
			if(radius > (unsigned)ctlMin(root->getWidth(), root->getHeight()) / 2)
				radius = (unsigned)ctlMin(root->getWidth(), root->getHeight() / 2);
			unsigned pos = horizontalLine.pos;
			int w = 1, p = pos;
			if(pos >= root->getHeight() - radius) {
				p = root->getHeight() - pos;
			}
			if(pos <= radius) 
			{
				w = static_cast<int>(radius - static_cast<int>(
					std::sqrt(static_cast<float>(
					((radius * p) << 1) - p * p)))
					+ ((radius - p) >> 2)) + 1;		//这考虑到反走样的部分
			}
			if((w << 1) <= root->getWidth() - 2)
			{
				common_draw_line(info, horizontalLine.color, 
					ctlPoint(root->getLeft() + w, root->getTop() + pos),
					ctlPoint(root->getRight() - w, root->getTop() + pos));
			}
		}
	}
	//绘制圆角的渐变矩形
	static ctlColor round_gradient_draw(_ctlInterior::drawInfo* info, IRound* root, ctlStyleBase* styleBase, ctlRect drawrect, 
		bool drawborder = true, bool autoParse = true, ctlDoubleColor xfill = ctlDoubleColor(), ctlDoubleColor xborder = ctlDoubleColor())
	{
		//绘制gradient样式button
		ctlStyleGradient* gradient = static_cast<ctlStyleGradient*>(styleBase);
		MAKE_POSITION(drawrect);
		ctlDoubleColor fill, border;
		ctlColor textColor = 0;
		//获取颜色数据
		if(autoParse)
			parse_color_data(root, gradient, border, fill, textColor, false);
		else border = xborder, fill = xfill;
		MK_ADDITION_4;
		Graphics* graphics = (Graphics*)info->graphics;
		//Color RGBA
		if(gradient->gradientDirection == ctlStyleGradient::reverse_horizontal ||
			gradient->gradientDirection == ctlStyleGradient::reverse_vertical)
		{
			std::swap(fill.crBegin, fill.crEnd);
			std::swap(border.crBegin, border.crEnd);
		}
		if(gradient->gradientDirection == ctlStyleGradient::horizontal ||
			gradient->gradientDirection == ctlStyleGradient::reverse_horizontal)
		{
			MAKE_GRADIENT_BRUSH32_H(pen_brush, border);
			MAKE_GRADIENT_BRUSH32_H(brush, fill);
			Pen pen(&pen_brush);
			round_common_draw(*graphics, brush, pen, left, top, width, height, root, drawborder);
		} else {
			MAKE_GRADIENT_BRUSH32(pen_brush, border);
			MAKE_GRADIENT_BRUSH32(brush, fill);
			Pen pen(&pen_brush);
			round_common_draw(*graphics, brush, pen, left, top, width, height, root, drawborder);
		}
		round_extra_line(info, root, gradient->horizontalLine);
		return textColor;
	}
	//绘制圆角的实色矩形
	static ctlColor round_solid_draw(_ctlInterior::drawInfo* info, IRound* root, ctlStyleBase* styleBase,  ctlRect drawrect, 
		bool drawborder = true, bool autoParse = true, ctlColor xfill = 0, ctlColor xborder = 0)
	{
		//绘制solid样式的button
		ctlStyleSolid* solid = static_cast<ctlStyleSolid*>(styleBase);
		MAKE_POSITION(drawrect);
		ctlColor fill, border, textColor;
		//获取颜色数据
		if(autoParse)
			parse_color_data(root, solid, border, fill, textColor, false);
		else fill = xfill, border = xborder;
		MK_ADDITION_2;

		Graphics* graphics = (Graphics*)info->graphics;
		SolidBrush brush(Color(MAKE_COLOR32(fill)));
		Pen pen(Color(MAKE_COLOR32(border)));
		round_common_draw(*graphics, brush, pen, left, top, width, height, root, drawborder);
		round_extra_line(info, root, solid->horizontalLine);
		return textColor;
	}

	//button绘制部分
	void ctlButton::_redraw_(_ctlInterior::drawInfo* info)
	{
		ctlColor textcolor = 0;
		ctlStyleBase* style_ptr = _styleBase;
		if(isSelectedEnabled() && isSelected())
			style_ptr = _button_style.get();
		if(style_ptr == nullptr) return;
		if(isAsStatic() == false)
		{
			if(isRoundEnabled())
			{
				if(style_ptr->styleType == ctlStyleType::gradient)
					textcolor = round_gradient_draw(info, this, style_ptr, getRect());
				else if(style_ptr->styleType == ctlStyleType::solid) 
					textcolor = round_solid_draw(info, this, style_ptr, getRect());
			} else {
				if(style_ptr->styleType == ctlStyleType::gradient)
					textcolor = common_gradient_draw(info, this, style_ptr, getRect());
				else if(style_ptr->styleType == ctlStyleType::solid) 
					textcolor = common_solid_draw(info, this, style_ptr, getRect());
			}
		} else {
			ctlStyleGradient* br = style_cast<ctlStyleGradient*>(style_ptr);
			ctlStyleSolid* sr = style_cast<ctlStyleSolid*>(style_ptr);
			ctlDoubleColor borderg, fillg;
			ctlColor borders, fills;
			if(br != nullptr) borderg = br->border.leave, fillg = br->fill.leave;
			if(br != nullptr && !isEnabled())
				borderg = br->border.disenable, fillg = br->fill.disenable;
			if(sr != nullptr) borders = sr->border.leave, fills = sr->fill.leave;
			if(sr != nullptr && !isEnabled())
				borders = sr->border.disenable, fills = sr->fill.disenable;
			if(isRoundEnabled())
			{
				if(style_ptr->styleType == ctlStyleType::gradient)
					textcolor = round_gradient_draw(info, this, style_ptr, getRect(), 
					true, false, fillg, borderg);
				else if(style_ptr->styleType == ctlStyleType::solid) 
					textcolor = round_solid_draw(info, this, style_ptr, getRect(),
					true, false, fills, borders);
			} else {
				if(style_ptr->styleType == ctlStyleType::gradient)
					textcolor = common_gradient_draw(info, this, style_ptr, getRect(), 
					false, true, false, fillg, borderg);
				else if(style_ptr->styleType == ctlStyleType::solid) 
					textcolor = common_solid_draw(info, this, style_ptr, getRect(),
					false, true, false, fills, borders);
			}
		}
		_notify_draw_event_(info, true);
		_draw_text_(info, textcolor, _textRect);
		_notify_draw_event_(info, false);
	}
	//static绘制部分
	void ctlStatic::_redraw_(_ctlInterior::drawInfo* info)
	{
		_notify_draw_event_(info, true);
		_background_redraw(info);
		_notify_draw_event_(info, false);
	}
	void ctlSingleLabel::_redraw_(_ctlInterior::drawInfo* info)
	{
		_background_redraw(info);
		_notify_draw_event_(info, true);
		FORMAT_TEXT_ALIGN;
		RECT rc;
		SetRect(&rc, getLeft() + getPadding().getLeft(), 
			getTop() + getPadding().getTop(), 
			getRight() + getPadding().getWidth(),
			getBottom() + getPadding().getHeight());
		common_text_draw(info, getTextColor(), 
			rc, _textpack, format | DT_WORD_ELLIPSIS, 
			reinterpret_cast<HFONT>(getFont()->getNativeHandle()), 
			true, _eventTrans.getMajorInfo()->tempAlpha);
		_notify_draw_event_(info, false);
	}
	//scroll绘制部分
	void ctlScroll::_redraw_(_ctlInterior::drawInfo* info)
	{
		if(_styleBase == 0) return;
		if(_styleBase->styleType == ctlStyleType::gradient)
			common_gradient_draw(info, this, _styleBase, getRect());
		else if(_styleBase->styleType == ctlStyleType::solid) 
			common_solid_draw(info, this, _styleBase, getRect());
	}
	//checkbox绘制部分
	void ctlCheckBox::_redraw_(_ctlInterior::drawInfo* info)
	{
		if(_styleBase == 0) return;
		ctlColor textcolor = 0, selectcolor = 0;
		ctlRect drawrect = _getBoxRect();
		if(_styleBase->styleType == ctlStyleType::gradient)
		{
			textcolor = common_gradient_draw(info, this, _styleBase, drawrect, isSelected());
			selectcolor = isEnabled() ? ((ctlStyleGradient*)_styleBase)->crSelectedFlag
				: ((ctlStyleGradient*)_styleBase)->crDisenabledSelectedFlag;
		} else if(_styleBase->styleType == ctlStyleType::solid) {
			textcolor = common_solid_draw(info, this, _styleBase, drawrect, isSelected());
			selectcolor = isEnabled() ? ((ctlStyleSolid*)_styleBase)->crSelectedFlag
				: ((ctlStyleSolid*)_styleBase)->crDisenabledSelectedFlag;
		}
		if(isSelected())
		{
			//绘制选中标志
			const int fillWidth = 4;
			ctlRect boxRect = drawrect;
			boxRect.cx -= fillWidth * 2, boxRect.cy -= fillWidth * 2;
			boxRect.x += fillWidth, boxRect.y += fillWidth;
			RECT rc = MAKE_RECT(boxRect);
			HBRUSH hBrush = CreateSolidBrush(MAKE_SYSTEM_RGB(selectcolor));
			FillRect(info->hDC, &rc, hBrush);
			DeleteObject(hBrush);
		}
		_draw_text_(info, textcolor, ctlRect(ctlSelectableBox::BoxWidth + ctlSelectableBox::TextOffset, 0, 
				getWidth() - (ctlSelectableBox::BoxWidth + ctlSelectableBox::TextOffset), getHeight()));
	}
	void ctlList::_redraw_(_ctlInterior::drawInfo* info)
	{
		_background_redraw(info);
	}
	//radiobox绘制部分
	void ctlRadioBox::_redraw_(_ctlInterior::drawInfo* info)
	{
		if(_styleBase == 0) return;
		ctlColor textcolor = 0, selectcolor = 0;
		ctlRect drawrect = _getBoxRect();
		if(_styleBase->styleType == ctlStyleType::gradient)
		{
			textcolor = common_gradient_draw_circle(info, this, _styleBase, drawrect, isSelected());
			selectcolor = isEnabled() ? ((ctlStyleGradient*)_styleBase)->crSelectedFlag
				: ((ctlStyleGradient*)_styleBase)->crDisenabledSelectedFlag;
		} else if(_styleBase->styleType == ctlStyleType::solid) {
			textcolor = common_solid_draw_circle(info, this, _styleBase, drawrect, isSelected());
			selectcolor = isEnabled() ? ((ctlStyleSolid*)_styleBase)->crSelectedFlag
				: ((ctlStyleSolid*)_styleBase)->crDisenabledSelectedFlag;
		}
		if(isSelected())
		{
			//绘制选中标志
			const int fillWidth = 4;
			Rect boxRect(drawrect.x, drawrect.y, drawrect.cx, drawrect.cy);
			boxRect.Width -= fillWidth * 2, boxRect.Height -= fillWidth * 2;
			boxRect.X += fillWidth, boxRect.Y += fillWidth;
			Graphics* graphics = (Graphics*)info->graphics;

			SolidBrush brush(MAKE_COLOR24(selectcolor));
			boxRect.Width -= 1, boxRect.Height -= 1;
			graphics->FillEllipse(&brush, boxRect);
		}
		_draw_text_(info, textcolor, ctlRect(ctlSelectableBox::BoxWidth + ctlSelectableBox::TextOffset, 0, 
				getWidth() - (ctlSelectableBox::BoxWidth + ctlSelectableBox::TextOffset), getHeight()));
	}
	void ctlProgress::_redraw_(_ctlInterior::drawInfo * info)
	{
		if(_styleBase == 0) return;
		ctlRect rect2 = getRect();
		ctlStyleProgress* style = style_cast<ctlStyleProgress*>(_styleBase);
		bool useGdip = isRoundEnabled() || style->isColor32();
		if(getBarDirection() == ctlScrollDirection::vertical)
		{
			rect2.cy = ctlMin(static_cast<int>(getHeight() * getPercentProgress()), getHeight());
			rect2.y = getBottom() - rect2.cy;
		} else {
			rect2.y = getTop();
			rect2.cx = ctlMin(static_cast<int>(getWidth() * getPercentProgress()), getWidth() - 2);
		}
		Graphics* graphics = reinterpret_cast<Graphics*>(info->graphics);
		bool bfsame = style->fill.crBegin == style->bkFill.crBegin
				&& style->fill.crEnd == style->bkFill.crEnd
				&& style->border.crBegin == style->bkBorder.crBegin
				&& style->border.crEnd == style->bkBorder.crEnd;
		if(useGdip)
		{
			ctlRect rect = getRect();
			auto lamDraw = [&](ctlRect rect, Brush& fill, Pen& pen, ctlDoubleColor& a, ctlDoubleColor& b)
			{
				MAKE_POSITION(rect);
				bool fcsame = a.crBegin == b.crBegin
					&& a.crEnd == b.crEnd;
				if(isRoundEnabled())
				{
					round_common_draw(*graphics, 
						fill, pen, left, top, width, height, this, !fcsame);
				} else { 
					graphics->FillRectangle(&fill, left, top, width - 1, height - 1);
					if(!fcsame) graphics->DrawRectangle(&pen, left, top, width - 1, height - 1);
				}
			};
			if(getBarDirection() == ctlScrollDirection::vertical)
			{
				MAKE_POSITION(rect);
				MAKE_GRADIENT_BRUSH32_H(fill, style->bkFill);
				MAKE_GRADIENT_BRUSH32_H(border, style->bkBorder);
				Pen pen(&border);
				lamDraw(rect, fill, pen, style->bkFill, style->bkBorder);
			} else {
				MAKE_POSITION(rect);
				MAKE_GRADIENT_BRUSH32(fill, style->bkFill);
				MAKE_GRADIENT_BRUSH32(border, style->bkBorder);
				Pen pen(&border);
				lamDraw(rect, fill, pen, style->bkFill, style->bkBorder);
			}
			if(getLogicProgress() != 0 && !bfsame)
			{
				MAKE_POSITION(rect2);
				if(getBarDirection() == ctlScrollDirection::vertical)
				{	
					MAKE_GRADIENT_BRUSH32_H(fill, style->fill);
					MAKE_GRADIENT_BRUSH32_H(borderb, style->border);
					Pen bp(&borderb);
					lamDraw(rect2, fill, bp, style->fill, style->border);
				} else {
					MAKE_GRADIENT_BRUSH32(fill, style->fill);
					MAKE_GRADIENT_BRUSH32(borderb, style->border);
					Pen bp(&borderb);
					lamDraw(rect2, fill, bp, style->fill, style->border);
				}
			}
		} else {
			int dir = GRADIENT_FILL_RECT_H;
			if(getBarDirection() == ctlScrollDirection::horizontal)
				dir = GRADIENT_FILL_RECT_V;
			common_gradient_draw_x(info, style->bkBorder, 
				style->bkFill, true, dir, getRect());
			if(getLogicProgress() && !bfsame)
			{
				common_gradient_draw_x(info, style->border, 
					style->fill, true, dir, rect2);
			}
		}
	}
	void ctlComboBox::_redraw_(_ctlInterior::drawInfo*)
	{

	}
	void ctlImageButton::_redraw_(_ctlInterior::drawInfo* info)
	{
		_notify_draw_event_(info, true);
		std::shared_ptr<ctlImage> img;
		unsigned char alpha;
		if(!isSelected() || !isSelectedEnabled())
		{
			if(!isEnabled()) img = getDisenabledImage(), alpha = getImageAlpha().disenable;
			else if(isMouseDown()) img = getDownImage(), alpha = getImageAlpha().down;
			else if(isMouseStay()) img = getStayImage(), alpha = getImageAlpha().stay;
			else img = getLeaveImage(), alpha = getImageAlpha().leave;
		} else {
			if(!isEnabled()) img = getSelectedImage().disenable, alpha = getSelectedImageAlpha().disenable;
			else if(isMouseDown()) img = getSelectedImage().down, alpha = getSelectedImageAlpha().down;
			else if(isMouseStay()) img = getSelectedImage().stay, alpha = getSelectedImageAlpha().stay;
			else img = getSelectedImage().leave, alpha = getSelectedImageAlpha().leave;
		}
		if(img.get() != nullptr)
		{
			draw_image(_rect, info, img, isScaleImage() ? ctlImageRepeat::scaleXY : ctlImageRepeat::noRepeatXY, 
				alpha, hasMask(), getMaskColor(), _eventTrans.getMajorInfo()->tempAlpha);
		}
		_notify_draw_event_(info, false);
	}
}